package com.hxrfid.system.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hxrfid.common.constant.Constants;
import com.hxrfid.common.constant.UserConstants;
import com.hxrfid.common.core.domain.PageQuery;
import com.hxrfid.common.core.domain.entity.SysDept;
import com.hxrfid.common.core.domain.entity.SysTenant;
import com.hxrfid.common.core.domain.entity.SysUser;
import com.hxrfid.common.core.page.TableDataInfo;
import com.hxrfid.common.enums.UserFlag;
import com.hxrfid.common.exception.ServiceException;
import com.hxrfid.common.helper.LoginHelper;
import com.hxrfid.common.utils.StringUtils;
import com.hxrfid.system.domain.bo.SysTenantBo;
import com.hxrfid.system.domain.vo.SysTenantVo;
import com.hxrfid.system.mapper.SysDeptMapper;
import com.hxrfid.system.mapper.SysTenantMapper;
import com.hxrfid.system.service.ISysConfigService;
import com.hxrfid.system.service.ISysTenantService;
import com.hxrfid.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 租户信息Service业务层处理
 *
 * @author ruoyi
 * @date 2022-11-08
 */
@RequiredArgsConstructor
@Service
public class SysTenantServiceImpl implements ISysTenantService {

    private final SysTenantMapper baseMapper;

    private final ISysUserService sysUserService;

    private final SysDeptMapper sysDeptMapper;

    private final ISysConfigService configService;

    /**
     * 查询租户信息
     */
    @Override
    public SysTenantVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询租户信息
     */
    @Override
    public SysTenantVo queryByTenantId(Long tenantId) {
        LambdaQueryWrapper<SysTenant> lqw = new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getTenantId, tenantId);
        return baseMapper.selectVoOne(lqw);
    }

    /**
     * 查询租户信息列表
     */
    @Override
    public TableDataInfo<SysTenantVo> queryPageList(SysTenantBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo);
        Page<SysTenantVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询租户信息列表
     */
    @Override
    public List<SysTenantVo> queryList(SysTenantBo bo) {
        LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 校验租户名称是否唯一
     *
     * @param tenantName 租户名称
     * @param tenantId 租户编码
     * @return 结果
     */
    @Override
    public String checkTenantNameUnique(Long tenantId, String tenantName) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
            .eq(SysTenant::getTenantName, tenantName)
            .ne(ObjectUtil.isNotNull(tenantId), SysTenant::getTenantId, tenantId));
        if (exist) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    private LambdaQueryWrapper<SysTenant> buildQueryWrapper(SysTenantBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysTenant> lqw = Wrappers.lambdaQuery();
        lqw.eq(ObjectUtil.isNotNull(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId());
        lqw.like(StringUtils.isNotBlank(bo.getTenantName()), SysTenant::getTenantName, bo.getTenantName());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), SysTenant::getAddress, bo.getAddress());
        lqw.like(StringUtils.isNotBlank(bo.getPhone()), SysTenant::getPhone, bo.getPhone());
        lqw.like(StringUtils.isNotBlank(bo.getEmail()), SysTenant::getEmail, bo.getEmail());
        lqw.eq(bo.getActiveTime() != null, SysTenant::getActiveTime, bo.getActiveTime());
        lqw.eq(bo.getActiveFlag() != null, SysTenant::getActiveFlag, bo.getActiveFlag());
        lqw.eq(bo.getTempId() != null, SysTenant::getTempId, bo.getTempId());
        lqw.eq(StringUtils.isNotBlank(bo.getRegionCodes()), SysTenant::getRegionCodes, bo.getRegionCodes());
        return lqw;
    }

    /**
     * 新增租户信息
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean insertByBo(SysTenantBo bo) {
        SysTenant add = BeanUtil.toBean(bo, SysTenant.class);
        validEntityBeforeSave(add);
        add.setTenantId(this.generateTenantId());
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            // 添加默认用户
            addDefaultUser(add);
        }
        return flag;
    }

    /**
     * 修改租户信息
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean updateByBo(SysTenantBo bo) {
        SysTenant update = BeanUtil.toBean(bo, SysTenant.class);
        validEntityBeforeSave(update);
        SysDept dept = sysDeptMapper.selectOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getParentId,100L).eq(SysDept::getTenantId,bo.getTenantId()));
        if(null!=dept){
            dept.setDeptName(bo.getTenantName());
            sysDeptMapper.updateById(dept);
        }
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SysTenant entity){
        if (null == entity.getActiveFlag()) {
            entity.setActiveFlag(Constants.FLAG_YES);
        }
        if (null == entity.getTempId()) {
            throw new ServiceException("请选择权限模板");
        }
        // 电话不能修改
        if (null != entity.getId()) {
            entity.setPhone(null);
        } else if (StringUtils.isBlank(entity.getPhone())) {
            throw new ServiceException("电话不能为空");
        }
        if (UserConstants.NOT_UNIQUE.equals(this.checkTenantNameUnique(entity.getTenantId(), entity.getTenantName()))) {
            throw new ServiceException((Objects.isNull(entity.getTenantId()) ? "新增" : "修改") + "租户'" + entity.getTenantName() + "'失败，租户名称已存在");
        }
    }

    /**
     * 批量删除租户信息
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    /**
     * 添加默认部门
     *
     * @param entity
     */
    private SysDept addDefaultDept(SysTenant entity) {
        SysDept dept = new SysDept();
        dept.setTenantId(entity.getTenantId());
        dept.setDeptName(entity.getTenantName());
        dept.setParentId(UserConstants.ROOT_DEP_ID);
        SysDept info = sysDeptMapper.selectById(dept.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
            throw new ServiceException("根部门停用，不允许新增");
        }
        dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
        dept.setPhone(entity.getPhone());
        LambdaQueryWrapper<SysDept> queryWrapper = Wrappers.<SysDept>query().lambda().eq(SysDept::getParentId, dept.getParentId())
            .eq(SysDept::getDelFlag, "0");
        long orderNum = sysDeptMapper.selectCount(queryWrapper) + 1;
        dept.setOrderNum((int) orderNum);
        dept.setEmail(entity.getEmail());
        dept.setLeader(entity.getTenantName());
        dept.setCreateBy(LoginHelper.getUsername());
        dept.setCreateTime(new Date());
        // 0正常1停用
        dept.setStatus("0");
        sysDeptMapper.insert(dept);
        return dept;
    }

    /**
     * 添加默认用户
     *
     * @param entity
     */
    private Integer addDefaultUser(SysTenant entity) {
        // 添加默认部门
        SysDept dept = addDefaultDept(entity);
        SysUser user = new SysUser();
        user.setTenantId(dept.getTenantId());
        user.setDeptId(dept.getDeptId());
        user.setUserName(entity.getAccount());
        user.setPhonenumber(entity.getPhone());
        user.setNickName("管理员" + entity.getTenantId());
        user.setEmail(entity.getEmail());
        // 0正常1停用
        user.setStatus("0");
        user.setCreateBy(dept.getCreateBy());
        user.setCreateTime(new Date());
        user.setRemark("租户管理员账号");
        // 用户标识，0超级管理员 1租户管理员 2普通用户
        user.setUserFlag(UserFlag.TENANT_ADMIN.getValue());
        String initPassword = configService.selectConfigByKey("sys.user.initPassword");
        user.setPassword(BCrypt.hashpw(initPassword));
        if (UserConstants.NOT_UNIQUE.equals(sysUserService.checkUserNameUnique(user.getUserName()))) {
            throw new ServiceException("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhonenumber())
            && UserConstants.NOT_UNIQUE.equals(sysUserService.checkPhoneUnique(user))) {
            throw new ServiceException("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
            && UserConstants.NOT_UNIQUE.equals(sysUserService.checkEmailUnique(user))) {
            throw new ServiceException("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        return sysUserService.insertUser(user);
    }

    /**
     * 生成租户编码
     * @return 租户编码
     */
    private Long generateTenantId() {
        LambdaQueryWrapper<SysTenant> queryWrapper = new LambdaQueryWrapper<>();
        for (int i = 0; i < 10; i++) {
            long id = RandomUtil.randomLong(1000, 9999);
            queryWrapper.clear();
            queryWrapper.eq(SysTenant::getTenantId, id);
            Long l = baseMapper.selectCount(queryWrapper);
            if (l == null || Long.valueOf(0).equals(l)) {
                return id;
            }
        }
        throw new ServiceException("租户编码重复");
    }

}
